﻿using System;
using System.Collections.Generic;
using System.Text;
using OpenComposite.EII.Repository;
using System.Data;
using OpenComposite.Base.Designer;
using System.Windows.Forms;
using System.Drawing;

namespace OpenComposite.EII.Designer.BObjects
{
	class BODesignController : DesignController
	{
		public BODesignController(RepositorySurfaceManager surfaceManager)
			: base(surfaceManager)
		{

		}

		public override bool Save()
		{
			return base.Save();
		}

		protected override void OnSaved()
		{
			base.OnSaved();
			_changed = false;
			IRepositoryExplorerView view = Global.Data.RepositoryService.GetService<IRepositoryExplorerView>();
			IRepositoryExplorerTree tree = view.CurrentRepositoryTree;
			if ( tree == null ) return;
			if ( this.DiagramItem == null ) return;
			Domain domain = Global.Data.RepositoryService.GetItem<Domain>(this.DiagramItem.DomainId);
			TreeNode tn = tree.FindTreeNode(domain);
			foreach ( TreeNode node in tn.Nodes ) {
				if ( node.Text == "Business Objects" ) {
					tree.UpdateSubTree(node.Tag as IRepositoryItem);
					view.SelectRepositoryItem(this.DiagramItem, false);
					return;
				}
			}
		}

		protected override void OnClosing(FormClosingEventArgs e)
		{
			//string msg = "Do you want to save the changes?";
			//DialogResult result = MessageBox.Show(msg, "Question", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
			//if ( result == DialogResult.Cancel ) {
			//    e.Cancel = true;
			//    return;
			//} else if ( result == DialogResult.Yes ) {
			//    using ( new OpenComposite.Base.WaitMouse() ) {
			//        this.Save();
			//    }
			//    //EventHandler tmp = this.Save;
			//    //if ( tmp != null )
			//    //    tmp(this, e);
			//}
		}

		protected override void OnLoaded()
		{
			this.RepositoryItem.ItemChanged += new OpenComposite.EII.Services.RepositoryChangedEventHandler(RepositoryItem_ItemChanged);
			for ( int i = 0; i < this.DesignerView.DesignerControls.Count; i++ ) {
				BusinessObjectSymbol boSymbol = this.DesignerView.DesignerControls[i] as BusinessObjectSymbol;
				if ( boSymbol == null ) continue;
				if ( boSymbol.BusinessObject == null ) {
					Route[] routes = this.DesignerView.GetRoutesEndToStart(boSymbol);
					foreach ( Route route in routes ) {
						route.Remove();
					}
					routes = this.DesignerView.GetRoutesStartToEnd(boSymbol);
					foreach ( Route route in routes ) {
						route.Remove();
					}
					this.DesignerView.DesignerControls.Remove(boSymbol);
				} else {
					boSymbol.BusinessObject.ItemDeleted += new OpenComposite.EII.Services.RepositoryEventHandler(RepositoryItem_ItemDeleted);
				}
			}
			base.OnLoaded();
		}

		void RepositoryItem_ItemDeleted(object sender, OpenComposite.EII.Services.RepositoryEventArgs e)
		{
			if ( this.DesignerView == null || this.DesignerView.DesignerControls == null ) return;
			for ( int i = 0; i < this.DesignerView.DesignerControls.Count; i++ ) {
				BusinessObjectSymbol boSymbol = this.DesignerView.DesignerControls[i] as BusinessObjectSymbol;
				if ( boSymbol == null ) continue;
				try {
					if ( boSymbol.BusinessObject == e.RepositoryItem ) {
						boSymbol.Remove();
						_changed = true;
					}
				} catch { }
			}
		}

		void RepositoryItem_ItemChanged(object sender, OpenComposite.EII.Services.RepositoryChangedEventArgs e)
		{
			if ( e.Member != null && e.Member.Name == "BusinessObjectFields" &&
				 e.NewValue is BusinessObjectField && e.OldValue is System.ComponentModel.CollectionChangeAction &&
				 e.RepositoryItem == this.RepositoryItem ) {
				_changed = true;
			}
		}

		protected override void SaveItems(List<DesignerControl> oldHierarchy)
		{
			RepositoryItemBase itemParent = _diagramItem;
			if ( itemParent == null )
				throw new Exception("No parent item available.");

			foreach ( DesignerControl dc in oldHierarchy ) {
				DeleteHierarchyRecursive(dc);
			}
			RecursiveSaveItems(this.DesignerView.MainControl, null);
			walkTheRoutes(this.DesignerView.MainControl);
		}

		private void walkTheRoutes(DesignerControl parent)
		{
			Route[] routes = this.DesignerView.GetRoutesStartToEnd(parent);
			if ( routes == null || routes.Length == 0 ) return;
			foreach ( Route route in routes ) {
				IRepositoryItemSymbol symbol = parent as IRepositoryItemSymbol;
				if ( symbol == null ) continue;
				RecursiveSaveItems(route.EndControl, symbol.RepositoryItem);
				walkTheRoutes(route.EndControl);
			}
		}

		protected override void OnDragDrop(DragEventArgs e)
		{
			_changed = true;
			Point dropPoint = this.DesignerView.PointToClient(new Point(e.X, e.Y));
			DesignerControl ctrl = this.DesignerView.GetDesignerControlAt(dropPoint);
			TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode;
			BusinessObject bo = null;
			if ( node != null ) {
				bo = node.Tag as BusinessObject;
			}
			if ( bo != null && node != null && ( ctrl == null || ctrl is Route ) ) {
				bo.ItemDeleted += new OpenComposite.EII.Services.RepositoryEventHandler(RepositoryItem_ItemDeleted);
				BusinessObjectSymbol symbol = Global.Data.RepositoryService.CreateDesignerControl(bo) as BusinessObjectSymbol;
				this.DesignerView.AddDesignerControl(symbol);
				symbol.Location = dropPoint;
				int modifier = 0;
				foreach ( BusinessObjectField field in bo.BusinessObjectFields ) {
					if ( field.BusinessObject != null ) {
						BusinessObjectSymbol child = Global.Data.RepositoryService.CreateDesignerControl(field.BusinessObject) as BusinessObjectSymbol;
						symbol.AddSymbolAsChild(symbol, child, modifier);
						modifier++;
					}
				}
			} else {
				//AddSymbolAsChild()
				base.OnDragDrop(e);
			}
		}
	}
}
